//
// Created by user on 20-5-5.
//

#include "SoftIRQ.h"
#include "../GeneralLibrary/Printf.h"

// 软中断状态全局变量，主要用于在中断返回时判断是否需要执行中断
unsigned long softIRQStatus = 0;

// 软中断向量表，用来存储软中断函数的表，默认64个
SoftIRQ softIRQCVector[64] = {0};

void softIRQInit() {

    // 1. 初始化软中断状态变量为不触发软中断
    softIRQStatus = 0;

    // 2. 清空软中断向量表占用的内存
    memset(softIRQCVector, 0, sizeof(SoftIRQ) * 64);

}

void setSoftIRQStatus(unsigned long status) {
    softIRQStatus |= status;
}

unsigned long getSoftIRQStatus() {
    return softIRQStatus;
}

void registerSoftIRQ(int nr, void (*action)(void *data), void *data) {

    // 1. 设置对应中断号的动作函数
    softIRQCVector[nr].action = action;

    // 2. 设置对应中断号的参数数据
    softIRQCVector[nr].data = data;

}

void unRegisterSoftIRQ(int nr) {

    // 1. 清空对应中断号的动作函数
    softIRQCVector[nr].action = NULL;

    // 2. 清空对应中断号的参数数据
    softIRQCVector[nr].data = NULL;
}

void doSoftIRQ() {

    // 1. 关中断，防止执行软中断的时候，发生中断
    cli();
//    sti();
    // 2.执行软中断函数列表
    for (int i = 0; i < 64 && softIRQStatus; i++) {
        if (softIRQStatus & (1 << i)) {
//            printfColor(INDIGO, BLACK, "in: %d\n", 64 && softIRQStatus);
            softIRQCVector[i].action(softIRQCVector[i].data);
            softIRQStatus &= ~(1 << i);
        }
    }

    // 3. 开中断
    sti();
//    cli();
}